/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef NDK_INCLUDE_NATIVE_IMAGE_H_
#define NDK_INCLUDE_NATIVE_IMAGE_H_

/**
 * @addtogroup OH_NativeImage
 * @{
 *
 * @brief Provides the capabilities of <b>NativeImage</b>. Functioning as a data consumer, this module is used to
 * associate data with the OpenGL texture. It is used in the OpenGL environment.
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @since 9
 * @version 1.0
 */

/**
 * @file native_image.h
 *
 * @brief Defines the functions for obtaining and using <b>NativeImage</b>.
 *
 * File to include: &lt;native_image/native_image.h&gt;
 * @library libnative_image.so
 * @since 9
 * @version 1.0
 */

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Defines the <b>OH_NativeImage</b> struct.
 * @since 9
 */
struct OH_NativeImage;

/**
 * @brief Defines the <b>OH_NativeImage</b> struct.
 * @since 9
 */
typedef struct OH_NativeImage OH_NativeImage;

/**
 * @brief Provides access to <b>NativeWindow</b>.
 * @since 9
 */
typedef struct NativeWindow OHNativeWindow;

/**
 * @brief Provides the declaration of a <b>NativeWindowBuffer</b> struct.
 * @since 12
 */
typedef struct NativeWindowBuffer OHNativeWindowBuffer;

/**
 * @brief Defines the callback function triggered when a frame is available.
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param context Defines user-defined context information, which is returned when the callback is triggered.
 * @since 11
 * @version 1.0
 */
typedef void (*OH_OnFrameAvailable)(void *context);

/**
 * @brief Defines an <b>OH_NativeImage</b> listener, which is registered through
 * {@link OH_NativeImage_SetOnFrameAvailableListener}.
 * The listener triggers a callback when a frame is available.
 *
 * @since 11
 * @version 1.0
 */
typedef struct OH_OnFrameAvailableListener {
    /** User-defined context information, which is returned when the callback is triggered. */
    void *context;
    /** Defines the callback function triggered when a frame is available. */
    OH_OnFrameAvailable onFrameAvailable;
} OH_OnFrameAvailableListener;

/**
 * @brief Enumerates the error codes.
 * @since 12
 */
typedef enum OHNativeErrorCode {
    /** The operation is successful. */
    NATIVE_ERROR_OK = 0,
    /**
     * An error occurs during memory manipulation.
     * @since 14
     */
    NATIVE_ERROR_MEM_OPERATION_ERROR = 30001000,
    /** An input parameter is invalid. */
    NATIVE_ERROR_INVALID_ARGUMENTS = 40001000,
    /** You do not have the permission to perform the operation. */
    NATIVE_ERROR_NO_PERMISSION = 40301000,
    /** No buffer is available. */
    NATIVE_ERROR_NO_BUFFER = 40601000,
    /** The consumer does not exist. */
    NATIVE_ERROR_NO_CONSUMER = 41202000,
    /** Not initialized. */
    NATIVE_ERROR_NOT_INIT = 41203000,
    /** The consumer is connected. */
    NATIVE_ERROR_CONSUMER_CONNECTED = 41206000,
    /** The buffer status does not meet the expectation. */
    NATIVE_ERROR_BUFFER_STATE_INVALID = 41207000,
    /** The buffer is already in the buffer queue. */
    NATIVE_ERROR_BUFFER_IN_CACHE = 41208000,
    /** The queue is full. */
    NATIVE_ERROR_BUFFER_QUEUE_FULL = 41209000,
    /** The buffer is not in the buffer queue. */
    NATIVE_ERROR_BUFFER_NOT_IN_CACHE = 41210000,
    /** The consumer is disconnected. */
    NATIVE_ERROR_CONSUMER_DISCONNECTED = 41211000,
    /** No listener is registered on the consumer side. */
    NATIVE_ERROR_CONSUMER_NO_LISTENER_REGISTERED = 41212000,
    /** The device or platform does not support the operation. */
    NATIVE_ERROR_UNSUPPORTED = 50102000,
    /** Unknown error. Check the log. */
    NATIVE_ERROR_UNKNOWN = 50002000,
    /** Failed to call the HDI. */
    NATIVE_ERROR_HDI_ERROR = 50007000,
    /** Cross-process communication failed. */
    NATIVE_ERROR_BINDER_ERROR = 50401000,
    /** The EGL environment is abnormal. */
    NATIVE_ERROR_EGL_STATE_UNKNOWN = 60001000,
    /** Failed to call the EGL APIs. */
    NATIVE_ERROR_EGL_API_FAILED = 60002000,
} OHNativeErrorCode;

/**
 * @brief Creates an <b>OH_NativeImage</b> instance to be associated with the OpenGL ES texture ID and target. \n
 * This function must be used in pair with {@link OH_NativeImage_Destroy}. Otherwise, memory leak occurs. \n
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param textureId OpenGL ES texture ID.
 * @param textureTarget OpenGL ES texture target.
 * @return Returns the pointer to the <b>OH_NativeImage</b> instance created;
 * returns <b>NULL</b> otherwise.
 * @since 9
 * @version 1.0
 */
OH_NativeImage* OH_NativeImage_Create(uint32_t textureId, uint32_t textureTarget);

/**
 * @brief Obtains an <b>OHNativeWindow</b> instance associated with an <b>OH_NativeImage</b> instance. \n
 * This function is not thread-safe. \n
 * When <b>OH_NativeImage</b> is being destructed, the corresponding <b>OHNativeWindow</b> instance is released.
 * If the <b>OHNativeWindow</b> pointer is obtained by using this function, set the pointer to null
 * when releasing the <b>OH_NativeImage</b> instance, so as to prevent subsequent wild pointers. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @return Returns a pointer to the <b>OHNativeWindow</b> instance if the operation is successful;
 * returns <b>NULL</b> otherwise.
 * @since 9
 * @version 1.0
 */
OHNativeWindow* OH_NativeImage_AcquireNativeWindow(OH_NativeImage* image);

/**
 * @brief Attaches an <b>OH_NativeImage</b> instance to the current OpenGL ES context.
 * The OpenGL ES texture will be bound to an <b>GL_TEXTURE_EXTERNAL_OES</b> instance and updated
 * through the <b>OH_NativeImage</b> instance. \n
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @param textureId ID of the OpenGL ES texture to which the <b>OH_NativeImage</b> instance is to be attached.
 * @return Returns <b>0</b> if the operation is successful;
 * returns an error code defined in {@link OHNativeErrorCode} otherwise.
 * @since 9
 * @version 1.0
 */
int32_t OH_NativeImage_AttachContext(OH_NativeImage* image, uint32_t textureId);

/**
 * @brief Detaches an <b>OH_NativeImage</b> instance from the current OpenGL ES context. \n
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @return Returns <b>0</b> if the operation is successful;
 * returns an error code defined in {@link OHNativeErrorCode} otherwise.
 * @since 9
 * @version 1.0
 */

int32_t OH_NativeImage_DetachContext(OH_NativeImage* image);

/**
 * @brief Updates the OpenGL ES texture associated with the latest frame through an <b>OH_NativeImage</b> instance. \n
 * This function must be called in a thread of the OpenGL ES context. \n
 * This function must be called after the {@link OH_OnFrameAvailableListener} callback is triggered. \n
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @return Returns <b>0</b> if the operation is successful;
 * returns an error code defined in {@link OHNativeErrorCode} otherwise.
 * @since 9
 * @version 1.0
 */
int32_t OH_NativeImage_UpdateSurfaceImage(OH_NativeImage* image);

/**
 * @brief Obtains the timestamp of the texture image
 * that recently called the <b>OH_NativeImage_UpdateSurfaceImage</b> function.
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @return Returns the timestamp of the texture image.
 * @since 9
 * @version 1.0
 */
int64_t OH_NativeImage_GetTimestamp(OH_NativeImage* image);

/**
 * @brief Obtains the transformation matrix of the texture image
 * that recently called the <b>OH_NativeImage_UpdateSurfaceImage</b> function.
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @param matrix Buffer used to store the 4 x 4 transformation matrix obtained.
 * @return Returns <b>0</b> if the operation is successful;
 * returns an error code defined in {@link OHNativeErrorCode} otherwise.
 * @since 9
 * @version 1.0
 * @deprecated This API is deprecated from API version 12. Use <b>OH_NativeImage_GetTransformMatrixV2</b> instead.
 */
int32_t OH_NativeImage_GetTransformMatrix(OH_NativeImage* image, float matrix[16]);

/**
 * @brief Obtains the surface ID of an <b>OH_NativeImage</b> instance. \n
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @param surfaceId Pointer to the surface ID.
 * @return Returns <b>0</b> if the operation is successful;
 * returns an error code defined in {@link OHNativeErrorCode} otherwise.
 * @since 11
 * @version 1.0
 */
int32_t OH_NativeImage_GetSurfaceId(OH_NativeImage* image, uint64_t* surfaceId);

/**
 * @brief Registers a listener to listen for frame availability events. \n
 * Do not call other functions of this module in the callback. \n
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @param listener Listener to register.
 * @return Returns <b>0</b> if the operation is successful;
 * returns an error code defined in {@link OHNativeErrorCode} otherwise.
 * @since 11
 * @version 1.0
 */
int32_t OH_NativeImage_SetOnFrameAvailableListener(OH_NativeImage* image, OH_OnFrameAvailableListener listener);

/**
 * @brief Deregisters the listener used to listen for frame availability events. \n
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @return Returns <b>0</b> if the operation is successful;
 * returns an error code defined in {@link OHNativeErrorCode} otherwise.
 * @since 11
 * @version 1.0
 */
int32_t OH_NativeImage_UnsetOnFrameAvailableListener(OH_NativeImage* image);

/**
 * @brief Destroys an <b>OH_NativeImage</b> instance created by calling <b>OH_NativeImage_Create</b>.
 * After the instance is destroyed, the pointer to the <b>OH_NativeImage</b> instance is assigned <b>NULL</b>. \n
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @since 9
 * @version 1.0
 */
void OH_NativeImage_Destroy(OH_NativeImage** image);

/**
 * @brief Obtains, based on the rotation angle set by the producer, the transformation matrix of the texture image
 * that recently called the <b>OH_NativeImage_UpdateSurfaceImage</b> function. \n
 * The matrix is updated only after {@link OH_NativeImage_UpdateSurfaceImage} is called. \n
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @param matrix Buffer used to store the 4 x 4 transformation matrix obtained.
 * @return Returns <b>0</b> if the operation is successful;
 * returns an error code defined in {@link OHNativeErrorCode} otherwise.
 * @since 12
 * @version 1.0
 */
int32_t OH_NativeImage_GetTransformMatrixV2(OH_NativeImage* image, float matrix[16]);

/**
 * @brief Obtains the transformation matrix calculated based on the rotation angle set by the producer and
 * the actual valid content area of the buffer.
 *
 * This function returns a transformation matrix that is determined by the buffer's rotation angle and
 * actual valid content area during the consumption of the buffer by {@link OH_NativeImage}, specifically when
 * invoking the functions {@link OH_NativeImage_UpdateSurfaceImage} or {@link OH_NativeImage_AcquireNativeWindowBuffer}.
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to the {@link OH_NativeImage} instance.
 * @param matrix Buffer used to store the 4 x 4 transformation matrix obtained.
 * @return Returns <b>NATIVE_ERROR_OK</b> if the operation is successful. \n
 * Returns <b>NATIVE_ERROR_INVALID_ARGUMENTS</b> (error code: 40001000) if <b>image</b> is a null pointer. \n
 * Returns <b>NATIVE_ERROR_MEM_OPERATION_ERROR</b> (error code: 30001000) if the transformation matrix fails
 * to be obtained due to a memory manipulation error.
 * @since 14
 * @version 1.0
 */
int32_t OH_NativeImage_GetBufferMatrix(OH_NativeImage* image, float matrix[16]);

/**
 * @brief Obtain an <b>OHNativeWindowBuffer</b> instance through an <b>OH_NativeImage</b> instance on the consumer side.
 * This API cannot be used together with {@link OH_NativeImage_UpdateSurfaceImage}. \n
 * This API creates an <b>OHNativeWindowBuffer</b>. \n
 * When using the <b>OHNativeWindowBuffer</b>, call {@link OH_NativeWindow_NativeObjectReference} to
 * increase its reference count by one. \n
 * When finishing using the <b>OHNativeWindowBuffer</b>, call {@link OH_NativeWindow_NativeObjectUnreference} to
 * decrease the reference count by one. \n
 * This API must be used in pair with {@link OH_NativeImage_ReleaseNativeWindowBuffer}. Otherwise, memory leak occurs.
 * When <b>fenceFd</b> is used up, you must close it. \n
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @param nativeWindowBuffer Double pointer to the <b>OHNativeWindowBuffer</b> instance obtained.
 * @param fenceFd Pointer to the file descriptor handle.
 * @return Returns <b>NATIVE_ERROR_OK</b> if the operation is successful. \n
 * Returns <b>NATIVE_ERROR_INVALID_ARGUMENTS</b> if <b>image</b>, <b>nativeWindowBuffer</b>, or <b>fenceFd</b>
 * is a null pointer. \n
 * Returns <b>NATIVE_ERROR_NO_BUFFER</b> if no buffer is available for consumption. \n
 * @since 12
 * @version 1.0
 */
int32_t OH_NativeImage_AcquireNativeWindowBuffer(OH_NativeImage* image,
    OHNativeWindowBuffer** nativeWindowBuffer, int* fenceFd);

/**
 * @brief Releases an <b>OHNativeWindowBuffer</b> instance through an <b>OH_NativeImage</b> instance. \n
 * The system will close <b>fenFd</b>. You do not need to close it. \n
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @param nativeWindowBuffer Pointer to an <b>OHNativeWindowBuffer</b> instance.
 * @param fenceFd File descriptor handle, which is used for concurrent synchronization control.
 * @return Returns <b>NATIVE_ERROR_OK</b> if the operation is successful. \n
 * Returns <b>NATIVE_ERROR_INVALID_ARGUMENTS</b> if <b>image</b> or <b>nativeWindowBuffer</b> is a null pointer. \n
 * Returns <b>NATIVE_ERROR_BUFFER_STATE_INVALID</b> if the status of <b>nativeWindowBuffer</b> is invalid. \n
 * Returns <b>NATIVE_ERROR_BUFFER_NOT_IN_CACHE</b> if <b>nativeWindowBuffer</b> is not in the cache. \n
 * @since 12
 * @version 1.0
 */
int32_t OH_NativeImage_ReleaseNativeWindowBuffer(OH_NativeImage* image,
    OHNativeWindowBuffer* nativeWindowBuffer, int fenceFd);

/**
 * @brief Creates an <b>OH_NativeImage</b> instance to serve as the consumer of the surface. \n
 * This function is used only for memory cycling of the surface consumer.
 * Memory rendering is not proactively performed in the created <b>OH_NativeImage</b> instance. \n
 * This function cannot be used together with {@link OH_NativeImage_UpdateSurfaceImage}. \n
 * This function must be used in pair with {@link OH_NativeImage_AcquireNativeWindowBuffer} and
 * {@link OH_NativeImage_ReleaseNativeWindowBuffer}. \n
 * This function must be used in pair with {@link OH_NativeImage_Destroy}. Otherwise, memory leak occurs. \n
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @return Returns a pointer to the <b>OH_NativeImage</b> instance if the operation is successful;
 * returns <b>NULL</b> otherwise.
 * @since 12
 * @version 1.0
 */
OH_NativeImage* OH_ConsumerSurface_Create();

/**
 * @brief Sets the default read/write mode.
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @param usage Read/write mode. For details about the available options, see {@link OH_NativeBuffer_Usage}.
 * @return Returns <b>NATIVE_ERROR_OK</b> if the operation is successful. \n
 * Returns <b>NATIVE_ERROR_INVALID_ARGUMENTS</b> if <b>image</b> is a null pointer. \n
 * @since 13
 * @version 1.0
 */
int32_t OH_ConsumerSurface_SetDefaultUsage(OH_NativeImage* image, uint64_t usage);

/**
 * @brief Sets the default size of a geometric shape.
 * This function is not thread-safe. \n
 *
 * @syscap SystemCapability.Graphic.Graphic2D.NativeImage
 * @param image Pointer to an <b>OH_NativeImage</b> instance.
 * @param width Width of the geometric shape. The value is greater than 0, in pixels.
 * @param height Height of the geometric shape. The value is greater than 0, in pixels.
 * @return Returns <b>NATIVE_ERROR_OK</b> if the operation is successful. \n
 * Returns <b>NATIVE_ERROR_INVALID_ARGUMENTS</b> if <b>image</b> is a null pointer or
 * <b>width</b> or <b>height</b> is less than 0. \n
 * @since 13
 * @version 1.0
 */
int32_t OH_ConsumerSurface_SetDefaultSize(OH_NativeImage* image, int32_t width, int32_t height);
#ifdef __cplusplus
}
#endif

/** @} */
#endif
